const socketio = require('@feathersjs/socketio');
const WebSocket = require('ws');
const Sequelize = require('sequelize')
const rp  = require('request-promise')
var Agent = require('socks5-https-client/lib/Agent');
const schedule = require('node-schedule');

const key = '637DDB1B-C7D1-4355-BFD9-4A623C0F142D';
var redis = require("redis"),
    client = redis.createClient({
      host: '47.75.114.151',
      port: '6379'
    });
    //定时清除redis数据

function request(url) {
  return rp({
    url: `https://rest.coinapi.io${url}`,
    json: true,
    headers: {
     'X-CoinAPI-Key': key
    },
    strictSSL: true,
    /*agentClass: Agent,
    agentOptions: {
      socksHost: 'localhost', // Defaults to 'localhost'.
      socksPort: 1086, // Defaults to 1080.
    }*/
  });
}
function unique(array) {
  var res = array.filter(function(item, index, array){
      return array.indexOf(item) === index;
  })
  return res;
}
let coinOpenPrice={}
let exchangeArray = []
schedule.scheduleJob('* * 0 * * *', function(){
  exchangeArray.forEach(item =>{
    client.hgetall(item,async (err, replies)=>{
      if(err) {
        return
      }
      const newTimer = Date.parse(new Date())
      for(let key in replies) {
        if((newTimer-key)/1000>86400) {
          await new Promise(resolve=>{
            client.hdel(item,key,()=>{
              resolve(true)
            })
          })
        }
      }
    })
  })
});

module.exports = function(app) {
  app.configure(socketio(async function(io) {
    const sequelize = app.get('sequelizeClient')
    const quoteArray = await sequelize.query('SELECT distinct asset_id_quote as quote_coin FROM payroll.trade_pair;',{ type: Sequelize.QueryTypes.SELECT})
    const coinArray = quoteArray.map(({quote_coin}) => {
      return quote_coin
    })
    const newCoinArray = unique(coinArray) || []
    let resultObj = {
      price:'',
      ask_price:'',
      bid_price:'',
      rate: '',
      sum: '',
      size: ''
    };
    let res = {},templateRes = {};
    res = await new Promise((resolve)=> {
      let obj = {};
      newCoinArray.map(async (item, index) => {
        obj[item] = []
        const subRes = await sequelize.query(`SELECT distinct asset_id_base as base_coin FROM payroll.trade_pair where asset_id_quote = '${item}';`,{ type: Sequelize.QueryTypes.SELECT})
        const baseCoinArray = subRes.map(({base_coin}) => {
          return base_coin
        })
        const newBaseCoinArray = unique(baseCoinArray) || []
        const subObj = {}
        newBaseCoinArray.forEach(sunItem => {
          subObj[sunItem] = resultObj
        })
        obj[item] = subObj
        if(index === newCoinArray.length-1) {
          resolve(obj)
        }
      })
    })
    templateRes = JSON.parse(JSON.stringify(res))
    let isSuccess = true
    io.on('connection', function(socket) {
      var ws = new WebSocket('wss://ws.coinapi.io/v1/');
      ws.on('open', function open() {
        var hello = {
          "type": "hello",
          "apikey": "637DDB1B-C7D1-4355-BFD9-4A623C0F142D",
          "heartbeat": false,
          "subscribe_filter_symbol_id":[
            'HUOBIPRO_SPOT_'
          ],
          subscribe_filter_asset_id: newCoinArray,
          "subscribe_data_type": ["trade",'quote']
        };
        ws.send(JSON.stringify(hello));
      });
      ws.on('message', function incoming(data) {
        const obj = JSON.parse(data)

        if(obj.type === 'error') {
          return
        }
        const symbol_id = obj.symbol_id.split('_')
        const val = res[symbol_id[3]]
        let isReturn = false;
        for(let key in val) {
          const subVal = val[symbol_id[2]]
          if(subVal) {
            if(obj.type === 'trade') {
              const len = (exchangeArray.filter(item=>{
                return item ===`${symbol_id[2]}_${symbol_id[3]}`
              })).length
              if(len<1) {
                exchangeArray.push(`${symbol_id[2]}_${symbol_id[3]}`)
              }
              client.hset(`${symbol_id[2]}_${symbol_id[3]}`,Date.parse(new Date()),  `${obj.price}_${obj.size}`);
            }
            isReturn = false
            if(obj.type === 'trade' && !subVal.price) {
              subVal.coin = symbol_id[2]
              subVal.price = obj.price
              const openPrice = coinOpenPrice[`${symbol_id[2]}_${symbol_id[3]}`]
              if(openPrice!==undefined) {
                subVal.rate = ((subVal.price-openPrice)/openPrice *100).toFixed(2)
                console.log('-',symbol_id[2],symbol_id[3],subVal.rate)
              } else {
                request(`/v1/ohlcv/${symbol_id[2]}/${symbol_id[3]}/latest?period_id=1MIN&limit=1`)
                .then(result =>{
                  subVal.rate = ((subVal.price-result[0].price_open)/result[0].price_open *100).toFixed(2)
                  coinOpenPrice[`${symbol_id[2]}_${symbol_id[3]}`] = result[0].price_open
                  console.log(symbol_id[2],symbol_id[3],result[0].price_open)
                })
                .catch(e=> {
                  console.log(e)
                })
              }
              client.hgetall(`${symbol_id[2]}_${symbol_id[3]}`,(err, replies)=>{
                if(err) {
                  return
                }
                let sum = 0,size = 0
                for(let key in replies) {
                  const value = replies[key].split('_')
                  sum += Number(value[0]) * Number(value[1])
                  size += Number(value[1])
                }
                console.log('计算结束');
                subVal.sum = sum.toFixed(2)
                subVal.size = size.toFixed(2)
              })
            }
            if(obj.type === 'quote' && !subVal.bid_price) {
              subVal.ask_price = obj.ask_price
              subVal.bid_price = obj.bid_price
            }
          } else {
            isReturn = true
          }
        }
        if(isReturn) {
          return
        }
        isSuccess = true
        Object.keys(res).forEach(k => {
          const item = res[k]
          for(let key in item) {
            const result = Object.keys(item[key]).filter(subKey => {
              return item[key][subKey] ===''
            })
            if(result.length!==0) {
              isSuccess = false
            }
          }
        })
        if(isSuccess) {
          console.log('数据发送完成！');
          socket.emit('quoteWSData', res);
          res = JSON.parse(JSON.stringify(templateRes))
        }
     
      })
    });
  
    // Registering Socket.io middleware
    io.use(function (socket, next) {
      // Exposing a request property to services and hooks
      socket.feathers.referrer = socket.request.referrer;
      next();
    });
  }));
};
